package com.gome.ocean.common.utils;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;


/**
 * 文件读取工具
 * 
 * @author haqiaolong 2016年1月28日 下午5:45:14
 * @since 5.0.0
 */
public final class IOUtils {

    private static final int   BUFFER_SIZE            = 1024 * 8;
    public static final String DEFAULT_LOG_RESULT     = "result";
    public static final String DEFAULT_LOG_BEGININDEX = "beginIndex";

    private IOUtils(){
    }

    /**
     * write.
     * 
     * @param is InputStream instance.
     * @param os OutputStream instance.
     * @return count.
     * @throws java.io.IOException.
     */
    public static long write(InputStream is, OutputStream os) throws IOException {
        return write(is, os, BUFFER_SIZE);
    }

    /**
     * write.
     *
     * @param is InputStream instance.
     * @param os OutputStream instance.
     * @return count.
     * @throws java.io.IOException.
     */
    public static long write(String data, OutputStream os) throws IOException {
        return write(new ByteArrayInputStream(data.getBytes()), os, BUFFER_SIZE);
    }

    /**
     * write.
     * 
     * @param is InputStream instance.
     * @param os OutputStream instance.
     * @param bufferSize buffer size.
     * @return count.
     * @throws java.io.IOException.
     */
    public static long write(InputStream is, OutputStream os, int bufferSize) throws IOException {
        try {
            int read;
            long total = 0;
            byte[] buff = new byte[bufferSize];
            while (is.available() > 0) {
                read = is.read(buff, 0, buff.length);
                if (read > 0) {
                    os.write(buff, 0, read);
                    total += read;
                }
            }
            return total;
        } finally {
            is.close();
            os.close();
        }

    }

    /**
     * read string.
     * 
     * @param reader Reader instance.
     * @return String.
     * @throws java.io.IOException
     */
    public static String read(Reader reader) throws IOException {
        StringWriter writer = new StringWriter();
        try {
            write(reader, writer);
            return writer.getBuffer().toString();
        } finally {
            writer.close();
        }
    }

    /**
     * write string.
     * 
     * @param writer Writer instance.
     * @param string String.
     * @throws java.io.IOException
     */
    public static long write(Writer writer, String string) throws IOException {
        Reader reader = new StringReader(string);
        try {
            return write(reader, writer);
        } finally {
            reader.close();
        }
    }

    /**
     * write.
     * 
     * @param reader Reader.
     * @param writer Writer.
     * @return count.
     * @throws java.io.IOException
     */
    public static long write(Reader reader, Writer writer) throws IOException {
        return write(reader, writer, BUFFER_SIZE);
    }

    /**
     * write.
     * 
     * @param reader Reader.
     * @param writer Writer.
     * @param bufferSize buffer size.
     * @return count.
     * @throws java.io.IOException
     */
    public static long write(Reader reader, Writer writer, int bufferSize) throws IOException {
        int read;
        long total = 0;
        char[] buf = new char[BUFFER_SIZE];
        while ((read = reader.read(buf)) != -1) {
            writer.write(buf, 0, read);
            total += read;
        }
        return total;
    }

    /**
     * read lines.
     * 
     * @param file file.
     * @return lines.
     * @throws java.io.IOException
     */
    public static String[] readLines(File file) throws IOException {
        if (file == null || !file.exists() || !file.canRead()) return new String[0];

        return readLines(new FileInputStream(file));
    }

    /**
     * 随机读取文件内容
     *
     * @param fileName 文件名
     * @throws IOException
     */
    public static Map<String, Object> readFileByRandomAccess(String fileName, Long beginIndex) throws IOException {
        if (beginIndex == null) beginIndex = 0l;
        RandomAccessFile randomFile = null;
        StringBuffer buffer = new StringBuffer();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            randomFile = new RandomAccessFile(fileName, "r");
            long fileLength = randomFile.length();
            if (beginIndex >= fileLength) { // 说明文件已经读取结束 返回
                resultMap.put(DEFAULT_LOG_BEGININDEX, -2);
                return resultMap;
            }
            randomFile.seek(beginIndex);
            byte[] bytes = new byte[BUFFER_SIZE];
            while (randomFile.read(bytes) != -1) {
                buffer.append(new String(bytes, "utf-8"));
                bytes = new byte[BUFFER_SIZE];// 每次读取完，清空缓冲区，防止乱码
            }
            resultMap.put(DEFAULT_LOG_RESULT, buffer.toString());
            resultMap.put(DEFAULT_LOG_BEGININDEX, fileLength);
            return resultMap;
        } finally {
            if (randomFile != null) {
                try {
                    randomFile.close();
                } catch (IOException e1) {
                }
            }
        }
    }

    /**
     * read lines . \r\n
     *
     * @param filePath
     * @return
     * @throws java.io.IOException
     */
    public static String readLines(String filePath) throws IOException {
        if (StringUtils.isEmpty(filePath)) return StringUtils.EMPTY;
        StringBuffer buffer = new StringBuffer();
        String[] lines = readLines(new FileInputStream(new File(filePath)));
        if (lines != null) {
            for (String line : lines) {
                buffer.append(line + "\r\n");
            }
            return buffer.toString();
        }
        return StringUtils.EMPTY;
    }

    /**
     * read lines.
     * 
     * @param is input stream.
     * @return lines.
     * @throws java.io.IOException
     */
    public static String[] readLines(InputStream is) throws IOException {
        List<String> lines = new ArrayList<String>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        try {
            String line;
            while ((line = reader.readLine()) != null)
                lines.add(line);
            return lines.toArray(new String[0]);
        } finally {
            reader.close();
        }
    }

    /**
     * write lines.
     * 
     * @param os output stream.
     * @param lines lines.
     * @throws java.io.IOException
     */
    public static void writeLines(OutputStream os, String[] lines) throws IOException {
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
        try {
            for (String line : lines)
                writer.println(line);
            writer.flush();
        } finally {
            writer.close();
        }
    }

    /**
     * write lines.
     * 
     * @param file file.
     * @param lines lines.
     * @throws java.io.IOException
     */
    public static void writeLines(File file, String[] lines) throws IOException {
        if (file == null) throw new IOException("File is null.");
        writeLines(new FileOutputStream(file), lines);
    }

    /**
     * append lines.
     * 
     * @param file file.
     * @param lines lines.
     * @throws java.io.IOException
     */
    public static void appendLines(File file, String[] lines) throws IOException {
        if (file == null) throw new IOException("File is null.");
        writeLines(new FileOutputStream(file, true), lines);
    }
    /**
     * @param InputStream is
     * @param Charset cs
     * @throws  java.io.IOException
     * */
    public static String toStringCharsetAndClose(InputStream is,Charset cs) throws IOException{
        try {
            return org.apache.commons.io.IOUtils.toString(is, cs);
        }finally{
            org.apache.commons.io.IOUtils.closeQuietly(is);
        }
    }

}
